local computer = require("computer")
local colors = require("lib.graphics.colors")
local ar = require("lib.graphics.ar")
local parser = require("lib.utils.parser")
local time = require("lib.utils.time")
local screen = require("lib.utils.screen")
local states = require("server.entities.states")
local serialization = require("serialization")
local powerDisplay = {}

local hudObjects = {}

local function getNewTable(size, value)
    local array = {}
    for i = 1, size, 1 do
        array[i] = value
    end
    return array
end

local function getAverage(array)
    local sum = 0
    for i = 1, #array, 1 do
        sum = sum + array[i]
    end
    return sum / #array
end

local function updateMaxEU(value)
    local file = io.open("/home/NIDAS/settings/maxWireless", "w")
    if file then
        file:write(serialization.serialize({maxCapacity = value}))
        file:close()
    end
end

local function getMaxEU()
    file = io.open("/home/NIDAS/settings/maxWireless", "r")
    local maxValue = 10e5
    if file ~= nil then
        local data = serialization.unserialize(file:read("*a"))
        if maxValue then
            maxValue = data.maxCapacity
        end
        file:close()
    end
    return maxValue
end

local updateInterval = 100
local MAX_VOLTAGE = 2147483640

local energyData = {
    intervalCounter = 1,
    readings = {},
    hourData = {intervalCounter = 1, readings = {}, average = 0, startTime = 0, endTime = 0},
    minuteData = {intervalCounter = 1, readings = {}, average = 0, startTime = 0, endTime = 0},
    startTime = 0,
    endTime = 0,
    updateInterval = updateInterval,
    energyPerTick = 0,
    offset = 0,
    highestInput = 1,
    highestOutput= -1,
    energyIn = getNewTable(updateInterval, 0),
    energyOut = getNewTable(updateInterval, 0),
    input = 0,
    output = 0,
    wirelessMode = false
}

local energyUnit = "EU"

function powerDisplay.changeColor(glasses, backgroundColor, primaryColor, accentColor)
    local graphics = require("lib.graphics.graphics")
    for i = 1, #hudObjects do
        if hudObjects[i] then
            if hudObjects[i].glasses ~= nil then
                if hudObjects[i].glasses.address == glasses then
                    if backgroundColor ~= nil then
                        for j = 1, #hudObjects[i].static do
                            hudObjects[i].static[j].setColor(screen.toRGB(backgroundColor))
                        end
                    end
                    if primaryColor ~= nil then
                        hudObjects[i].dynamic.energyBar.setColor(screen.toRGB(primaryColor))
                        hudObjects[i].dynamic.currentEU.setColor(screen.toRGB(primaryColor))
                    end
                    if accentColor ~= nil then
                        hudObjects[i].dynamic.maxEU.setColor(screen.toRGB(accentColor))
                        hudObjects[i].dynamic.percentage.setColor(screen.toRGB(accentColor))
                        hudObjects[i].dynamic.filltime.setColor(screen.toRGB(accentColor))
                    end
                end
            end
        end
    end
end

-- 新增函数：为右对齐模式创建独立的HUD元素
local function createRightAlignedHud(hudObject, x, y, w, h, borderColor, primaryColor, accentColor, compact)
    local hProgress = math.ceil(h * 0.4)
    local hDivisor = 3
    local hIO = h-hProgress-2*hDivisor-1

    -- 静态元素
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y}, w, h, borderColor, 0.6))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-2}, w, 5+hProgress, borderColor, 0.6))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-4}, w, 2, borderColor, 0.5))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-6}, w, 2, borderColor, 0.4))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-8}, w, 2, borderColor, 0.3))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-10}, w, 2, borderColor, 0.2))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y}, w, hDivisor, borderColor))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y+hDivisor+hProgress}, w, hDivisor, borderColor))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y+h-1}, w, 1, borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x, y+hDivisor},-- 左上角
        {x, y+hDivisor+hProgress},-- 左下角
        {x+3, y+hDivisor+hProgress},-- 右下角
        {x+3+hProgress, y+hDivisor},-- 右上角
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x+w-3, y+hDivisor},
        {x+w-3-hProgress, y+hDivisor+hProgress},
        {x+w, y+hDivisor+hProgress},
        {x+w, y+hDivisor},
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x, y+2*hDivisor+hProgress},
        {x, y+2*hDivisor+hProgress+hIO},
        {x+40, y+2*hDivisor+hProgress+hIO},
        {x+40+hIO, y+2*hDivisor+hProgress},
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x+w-30, y+2*hDivisor+hProgress},
        {x+w-30-hIO, y+2*hDivisor+hProgress+hIO},
        {x+w, y+2*hDivisor+hProgress+hIO},
        {x+w, y+2*hDivisor+hProgress},
        borderColor))

    -- 动态元素（右对齐特定位置）
    -- 右对齐模式下从右向左填充的能量条
    hudObject.dynamic.energyBar = ar.quad(hudObject.glasses,
			{x+w+1, y+hDivisor},
			{x+w+1+hProgress, y+hDivisor+hProgress},
			{x+w-3-hProgress, y+hDivisor+hProgress},
			{x+w-3, y+hDivisor},
        primaryColor)

    -- 右对齐：currentEU在右侧，maxEU在左侧
    hudObject.dynamic.currentEU = ar.text(hudObject.glasses, "", {x+w-90, y-9}, primaryColor)
    hudObject.dynamic.maxEU = ar.text(hudObject.glasses, "", {x+2, y-9}, accentColor)
    hudObject.dynamic.percentage = ar.text(hudObject.glasses, "", {x+w/2-5, y-9}, accentColor)
    hudObject.dynamic.wirelessEU = ar.text(hudObject.glasses, "", {x+w/2-5 + 50, y-9}, primaryColor)
    hudObject.dynamic.filltime = ar.text(hudObject.glasses, "Time to empty:", {x+40+hIO, y+2*hDivisor+hProgress+3}, colors.red, 0.7)
    hudObject.dynamic.fillrate = ar.text(hudObject.glasses, "", {x+w/2-10, y+2*hDivisor+hProgress+2}, borderColor)
    hudObject.dynamic.input = ar.text(hudObject.glasses, "", {x+7, y+2*hDivisor+hProgress}, primaryColor, 0.5)
    hudObject.dynamic.output = ar.text(hudObject.glasses, "", {x+1, y+2*hDivisor+hProgress + 6}, accentColor, 0.5)
    hudObject.dynamic.state = ar.text(hudObject.glasses, "", {x+w-95, y+2*hDivisor+hProgress+2}, colors.red)
    hudObject.dynamic.fillIndicator = ar.quad(hudObject.glasses,
		{x+w+1, y+hDivisor},
		{x+w+1+hProgress, y+hDivisor+hProgress},
		{x+w-3-hProgress, y+hDivisor+hProgress},
		{x+w-3, y+hDivisor},
        colors.golden, 0.7)

	hudObject.dynamic.nextUpdateText = ar.text(hudObject.glasses, "", {x+w-30, y+2*hDivisor+hProgress}, accentColor, 0.5)
    hudObject.dynamic.maxVoltageCurrent = ar.text(hudObject.glasses, "", {x+w-35, y+2*hDivisor+hProgress + 5}, accentColor, 0.5)
    -- 紧凑模式调整
    if compact then
        hudObject.dynamic.state.setPosition(x+w/2-15, y+hDivisor+2)
        hudObject.dynamic.filltime.setPosition(x+hProgress, y+hDivisor+2)
        hudObject.dynamic.maxEU.setPosition(x+2, y-9)       -- maxEU在左
        hudObject.dynamic.currentEU.setPosition(x+w-32, y-9) -- currentEU在右
        hudObject.dynamic.percentage.setPosition(x+w/2-10, y-9)
    end
end

-- 新增函数：为左对齐模式创建HUD元素
local function createLeftAlignedHud(hudObject, x, y, w, h, borderColor, primaryColor, accentColor, compact)
    local hProgress = math.ceil(h * 0.4)
    local hDivisor = 3
    local hIO = h-hProgress-2*hDivisor-1

    -- 静态元素
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y}, w, h, borderColor, 0.6))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-2}, w, 5+hProgress, borderColor, 0.6))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-4}, w, 2, borderColor, 0.5))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-6}, w, 2, borderColor, 0.4))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-8}, w, 2, borderColor, 0.3))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y-10}, w, 2, borderColor, 0.2))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y}, w, hDivisor, borderColor))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y+hDivisor+hProgress}, w, hDivisor, borderColor))
    table.insert(hudObject.static, ar.rectangle(hudObject.glasses, {x, y+h-1}, w, 1, borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x, y+hDivisor},
        {x, y+hDivisor+hProgress},
        {x+3+hProgress, y+hDivisor+hProgress},
        {x+3, y+hDivisor},
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x+w-1-hProgress, y+hDivisor},
        {x+w-1, y+hDivisor+hProgress},
        {x+w, y+hDivisor+hProgress},
        {x+w, y+hDivisor},
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x, y+2*hDivisor+hProgress},
        {x, y+2*hDivisor+hProgress+hIO},
        {x+30+hIO, y+2*hDivisor+hProgress+hIO},
        {x+30, y+2*hDivisor+hProgress},
        borderColor))

    table.insert(hudObject.static, ar.quad(hudObject.glasses,
        {x+w-40-hIO, y+2*hDivisor+hProgress},
        {x+w-40, y+2*hDivisor+hProgress+hIO},
        {x+w, y+2*hDivisor+hProgress+hIO},
        {x+w, y+2*hDivisor+hProgress},
        borderColor))

    -- 动态元素（左对齐特定位置）
    -- 左对齐模式下从左向右填充的能量条
    hudObject.dynamic.energyBar = ar.quad(hudObject.glasses,
        {x+3, y+hDivisor},
        {x+3+hProgress, y+hDivisor+hProgress},
        {x+3+hProgress, y+hDivisor+hProgress},
        {x+3, y+hDivisor},
        primaryColor)

    -- 左对齐：currentEU在左侧，maxEU在右侧
    hudObject.dynamic.currentEU = ar.text(hudObject.glasses, "", {x+2, y-9}, primaryColor)
    hudObject.dynamic.maxEU = ar.text(hudObject.glasses, "", {x+w-90, y-9}, accentColor)
    hudObject.dynamic.percentage = ar.text(hudObject.glasses, "", {x+w/2-5, y-9}, accentColor)
    hudObject.dynamic.wirelessEU = ar.text(hudObject.glasses, "", {x+w/2-5 + 50, y-9}, primaryColor)
    hudObject.dynamic.filltime = ar.text(hudObject.glasses, "Time to empty:", {x+30+hIO, y+2*hDivisor+hProgress+3}, colors.red, 0.7)
    hudObject.dynamic.fillrate = ar.text(hudObject.glasses, "", {x+w/2-10, y+2*hDivisor+hProgress+2}, borderColor)
    hudObject.dynamic.input = ar.text(hudObject.glasses, "", {x+w - 45, y+2*hDivisor+hProgress}, primaryColor, 0.5)
    hudObject.dynamic.output = ar.text(hudObject.glasses, "", {x+w - 39, y+2*hDivisor+hProgress + 6}, accentColor, 0.5)
    hudObject.dynamic.state = ar.text(hudObject.glasses, "", {x+w-95, y+2*hDivisor+hProgress+2}, colors.red)
    hudObject.dynamic.fillIndicator = ar.quad(hudObject.glasses,
        {x+3, y+hDivisor},
        {x+3+hProgress, y+hDivisor+hProgress},
        {x+3+hProgress, y+hDivisor+hProgress},
        {x+3, y+hDivisor},
        colors.golden, 0.7)

	hudObject.dynamic.nextUpdateText = ar.text(hudObject.glasses, "", {x+2, y+2*hDivisor+hProgress}, accentColor, 0.5)
    hudObject.dynamic.maxVoltageCurrent = ar.text(hudObject.glasses, "", {x+2, y+2*hDivisor+hProgress + 5}, accentColor, 0.5)

    -- 紧凑模式调整
    if compact then
        hudObject.dynamic.state.setPosition(x+w/2-15, y+hDivisor+2)
        hudObject.dynamic.filltime.setPosition(x+hProgress, y+hDivisor+2)
        hudObject.dynamic.maxEU.setPosition(x+w-32, y-9) -- maxEU在右
        hudObject.dynamic.currentEU.setPosition(x+2, y-9) -- currentEU在左
        hudObject.dynamic.percentage.setPosition(x+w/2-10, y-9)
    end
end

--Scales: Small = 1, Normal = 2, Large = 3, Auto = 4x to 10x (Even)
--Glasses is a table of all glasses you want to dispaly the data on, with optional colour data.
--Glass table format {glassProxy, [{resolutionX, resolutionY}], [scale], [borderColor], [primaryColor], [accentColor], [width], [heigth]}
--Only the glass proxy is required, rest have default values.
local currentEU = 0
local maxEU = getMaxEU()
local tick = 0
function powerDisplay.widget(glasses, data)
    if data ~= nil then
    if data.state ~= states.MISSING then

    --Wireless EU addition
    if energyData.wirelessMode or data.wirelessEU > 10000000 then
        energyData.wirelessMode = true
        currentEU = data.wirelessEU
        if currentEU > maxEU then
            maxEU = maxEU * 10
            updateMaxEU(maxEU)
        end
    else
        currentEU = math.abs(math.floor(data.storedEU))
        maxEU = math.abs(math.floor(data.EUCapacity))
    end

    local percentage = math.min(currentEU/maxEU, 1.0)
    if percentage >= 0.999 then
        currentEU = maxEU
        percentage = 1.0
    end

    tick = tick + 1
    if tick > 72100 then tick = 0 end
    --Update I/O
    if energyData.intervalCounter == 1 then
        energyData.startTime = computer.uptime()
        energyData.readings[1] = currentEU
    end
    if energyData.intervalCounter < energyData.updateInterval then
        energyData.intervalCounter = energyData.intervalCounter + 1
        energyData.energyIn[energyData.intervalCounter] = data.EUIn
        energyData.energyOut[energyData.intervalCounter] = data.EUOut
    end
    if energyData.intervalCounter == energyData.updateInterval then
        energyData.endTime = computer.uptime()
        energyData.readings[2] = currentEU

        energyData.input = getAverage(energyData.energyIn)
        energyData.output = getAverage(energyData.energyOut)

        local ticks = math.ceil((energyData.endTime - energyData.startTime) * 20)
        energyData.energyPerTick = math.floor((energyData.readings[2] - energyData.readings[1])/ticks)
        if energyData.energyPerTick >= 0 then
            if energyData.energyPerTick > energyData.highestInput then
                energyData.highestInput = energyData.energyPerTick
            end
        else
            if energyData.energyPerTick < energyData.highestOutput then
                energyData.highestOutput = energyData.energyPerTick
            end
        end
        energyData.intervalCounter = 1
    end
    energyData.offset = energyData.offset + 2
    if energyData.energyPerTick >= 0 then
        energyData.offset = energyData.offset + 10*(energyData.energyPerTick / energyData.highestInput)
    else
        energyData.offset = energyData.offset + 10*(energyData.energyPerTick / energyData.highestOutput)
    end

    --5 minute average
    if energyData.minuteData.intervalCounter == 1 then
        energyData.minuteData.startTime = computer.uptime()
        energyData.minuteData.readings[1] = currentEU
        energyData.minuteData.intervalCounter = energyData.minuteData.intervalCounter + 1
    end
    if tick % 6000 == 0 then
        energyData.minuteData.endTime = computer.uptime()
        energyData.minuteData.readings[2] = currentEU
        local ticks = math.ceil((energyData.minuteData.endTime - energyData.minuteData.startTime) * 20) + 1
        energyData.minuteData.average = ((energyData.minuteData.readings[2] - energyData.minuteData.readings[1])/ticks)

        energyData.minuteData.intervalCounter = 1
    end

    if energyData.hourData.intervalCounter == 1 then
        energyData.hourData.startTime = computer.uptime()
        energyData.hourData.readings[1] = currentEU
        energyData.hourData.intervalCounter = energyData.hourData.intervalCounter + 1
    end
    if tick % 72000 == 0 then
        energyData.hourData.endTime = computer.uptime()
        energyData.hourData.readings[2] = currentEU
        local ticks = math.ceil((energyData.hourData.endTime - energyData.hourData.startTime) * 20) + 1
        energyData.hourData.average = ((energyData.hourData.readings[2] - energyData.hourData.readings[1])/ticks)
        energyData.hourData.intervalCounter = 1
    end

    if #hudObjects < #glasses then
        for i = 1, #glasses do
            if glasses[i][1] == nil then
                error("Must provide glass proxy for energy display.")
            end
            table.insert(hudObjects,  {
                static          = {},
                dynamic         = {},
                glasses         = glasses[i][1],
                resolution      = glasses[i][2] or {2560, 1440},
                scale           = glasses[i][3] or 3,
                borderColor     = glasses[i][4] or colors.darkGray,
                primaryColor    = glasses[i][5] or colors.electricBlue,
                accentColor     = glasses[i][6] or colors.magenta,
                width           = 0,
                heigth          = 29,
                compactMode     = glasses[i][7] or false,
                rightAlign      = glasses[i][8] or false
            })
        end
    end
    for i = 1, #hudObjects do
        if hudObjects[i] then
            if hudObjects[i].width == 0 then
                hudObjects[i].width = screen.size(hudObjects[i].resolution, hudObjects[i].scale)[1]/2 - 91
            end
            local h = hudObjects[i].heigth
            local w = hudObjects[i].width
            local compact = (w < 250) or hudObjects[i].compactMode
            local rightAlign = hudObjects[i].rightAlign

            -- 计算位置 - 根据rightAlign配置决定
            local screenWidth = screen.size(hudObjects[i].resolution, hudObjects[i].scale)[1]
            local x = rightAlign and (screenWidth - w) or 0
            local y = screen.size(hudObjects[i].resolution, hudObjects[i].scale)[2] - h

            local hProgress = math.ceil(h * 0.4)
			local energyBarLength = w-4-hProgress
			local RightenergyBarLength = w+4
            local hDivisor = 3
            local hIO = h-hProgress-2*hDivisor-1

            if #hudObjects[i].static == 0 and #hudObjects[i].glasses ~= nil then
                local borderColor = hudObjects[i].borderColor
                local primaryColor = hudObjects[i].primaryColor
                local accentColor = hudObjects[i].accentColord

                -- 根据对齐模式选择创建HUD的方式
                if rightAlign then
                    createRightAlignedHud(hudObjects[i], x, y, w, h, borderColor, primaryColor, accentColor, compact)
                else
                    createLeftAlignedHud(hudObjects[i], x, y, w, h, borderColor, primaryColor, accentColor, compact)
                end
            end

            -- 更新能量条位置 - 根据对齐模式使用不同的更新逻辑
            if rightAlign then
				local barX1 = x+w+7 + hProgress - RightenergyBarLength*percentage
				local barX2 = x+w+7 - RightenergyBarLength*percentage

				hudObjects[i].dynamic.energyBar.setVertex(1, barX1, y+hDivisor)
				hudObjects[i].dynamic.energyBar.setVertex(2, barX2, y+hDivisor+hProgress)
            else
                -- 左对齐模式：从左向右填充
                local barX3 = x+3+hProgress+energyBarLength*percentage
                local barX4 = x+3+energyBarLength*percentage

                hudObjects[i].dynamic.energyBar.setVertex(3, barX3, y+hDivisor+hProgress)
                hudObjects[i].dynamic.energyBar.setVertex(4, barX4, y+hDivisor)
            end

            -- 根据对齐模式更新文本位置
            if compact then
                if currentEU > 9000000000000000000 then
                    hudObjects[i].dynamic.currentEU.setText(parser.metricNumber(currentEU))
                else
                    hudObjects[i].dynamic.currentEU.setText(string.format("%.2e " .. energyUnit, currentEU))
                end
            else
                if currentEU > 9000000000000000000 then
                    hudObjects[i].dynamic.currentEU.setText(string.format("%.2e " .. energyUnit, currentEU))
                else
                    hudObjects[i].dynamic.currentEU.setText(parser.splitNumber(currentEU).." "..energyUnit)
                end
            end

            if maxEU > 9000000000000000000 then
                hudObjects[i].dynamic.maxEU.setText(parser.metricNumber(maxEU))
                if rightAlign then
                    hudObjects[i].dynamic.maxEU.setPosition(x+2, y-9)  -- 右侧对齐时maxEU在左侧
                else
                    hudObjects[i].dynamic.maxEU.setPosition(x+w-60, y-9)  -- 左侧对齐时在右侧
                end
            else
                if compact then
                    hudObjects[i].dynamic.maxEU.setText(string.format("%.2e " .. energyUnit, maxEU))
                else
                    hudObjects[i].dynamic.maxEU.setText(parser.splitNumber(maxEU).." "..energyUnit)
                end

                if not compact then
                    if rightAlign then
                        -- 右侧对齐：maxEU在左侧
                        hudObjects[i].dynamic.maxEU.setPosition(x+2, y-9)
                    else
                        -- 左侧对齐：maxEU在右侧
                        hudObjects[i].dynamic.maxEU.setPosition(x+w-30-(4.5*#parser.splitNumber(maxEU)), y-9)
                    end
                end
            end

            -- 调整currentEU位置（非紧凑模式）
            if not compact and maxEU <= 9000000000000000000 then
                if rightAlign then
                    -- 右侧对齐：currentEU在右侧
                    hudObjects[i].dynamic.currentEU.setPosition(x+w-30-(4.5*#parser.splitNumber(currentEU)), y-9)
                else
                    -- 左侧对齐：currentEU在左侧
                    hudObjects[i].dynamic.currentEU.setPosition(x+2, y-9)
                end
            end

            --Show LSC EU if wireless mode, and if you are Sampsa :)
            if energyData.wirelessMode and hudObjects[i].glasses.getBindPlayers() == "Admin_XiaoMai" then
                hudObjects[i].dynamic.wirelessEU.setText(parser.metricNumber(math.abs(math.floor(data.storedEU))).." "..energyUnit)

            end

            local hIOString = ""
            if compact then
                hIOString = parser.metricNumber(energyData.energyPerTick)
            else
                hIOString = parser.splitNumber(energyData.energyPerTick)
            end
            hudObjects[i].dynamic.fillrate.setPosition(x+w/2-18-(#hIOString*1.6), y+2*hDivisor+hProgress+2)
			local nextUpdateIn = (energyData.updateInterval - energyData.intervalCounter) * 0.05  -- 0.05秒 per call
			local nextUpdateText = string.format("Next: %.1fs", nextUpdateIn)
			hudObjects[i].dynamic.nextUpdateText.setText(nextUpdateText)
			
			-- 计算并显示最大电压下的电流值
			local maxVoltageCurrent = currentEU / MAX_VOLTAGE
			local maxCurrentString
			if maxVoltageCurrent > 1 then
				if compact then
					maxCurrentString = string.format(parser.metricNumber(maxVoltageCurrent).."A MAX")
				else
					maxCurrentString = string.format("%.1fA MAX", maxVoltageCurrent)
				end
			else
				maxCurrentString = string.format("%.0fmA MAX", maxVoltageCurrent * 1000)
			end
			hudObjects[i].dynamic.maxVoltageCurrent.setText(maxCurrentString)

            if energyData.energyPerTick >= 0 then
                hudObjects[i].dynamic.fillrate.setText("+"..hIOString.." "..energyUnit.."/t")
                hudObjects[i].dynamic.fillrate.setColor(screen.toRGB(colors.lime))
            else
                hudObjects[i].dynamic.fillrate.setText(hIOString.." "..energyUnit.."/t")
                hudObjects[i].dynamic.fillrate.setColor(screen.toRGB(colors.red))
            end

            if energyData.wirelessMode then
                if energyData.minuteData.average < 0 then
                    hudObjects[i].dynamic.input.setText("5m: " .. parser.metricNumber(energyData.minuteData.average) .. " " .. energyUnit.."/t")
                else
                    hudObjects[i].dynamic.input.setText("5m: +" .. parser.metricNumber(energyData.minuteData.average) .. " " .. energyUnit.."/t")
                end
                if energyData.hourData.average < 0 then
                    hudObjects[i].dynamic.output.setText("1h: " .. parser.metricNumber(energyData.hourData.average) .. " " .. energyUnit.."/t")
                else
                    hudObjects[i].dynamic.output.setText("1h: +" .. parser.metricNumber(energyData.hourData.average) .. " " .. energyUnit.."/t")
                end
            else
                hudObjects[i].dynamic.input.setText("+" .. parser.metricNumber(energyData.input) .. " " .. energyUnit.."/t")
                hudObjects[i].dynamic.output.setText("-" .. parser.metricNumber(energyData.output) .. " " .. energyUnit.."/t")
            end

            local fillTimeString = ""
            local fillTime = 0
            if data.wirelessMode then
                hudObjects[i].dynamic.percentage.setText("")
            else
                if energyData.energyPerTick > 0 then
                    fillTime = math.floor((maxEU-currentEU)/(energyData.energyPerTick*20))
                    fillTimeString = "Full: " .. time.format(math.abs(fillTime))
                elseif energyData.energyPerTick < 0 then
                    fillTime = math.floor((currentEU)/(energyData.energyPerTick*20))
                    fillTimeString = "Empty: " .. time.format(math.abs(fillTime))
                else
                    fillTimeString = ""
                end
                if math.abs(fillTime) > 500000 or percentage < 0.05 then
                    hudObjects[i].dynamic.percentage.setPosition(x+w/2-20, y-9)
                    hudObjects[i].dynamic.percentage.setText(tostring(math.floor(percentage*10000000)/100000).."%")
                else
                    hudObjects[i].dynamic.percentage.setPosition(x+w/2-5, y-9)
                    hudObjects[i].dynamic.percentage.setText(parser.percentage(percentage))
                end
            end

            if data.state == states.OFF then
                hudObjects[i].dynamic.state.setText("Disabled")
            else
                if data.problems > 0 then
                    hudObjects[i].dynamic.state.setText("Maintenance")
                else
                    hudObjects[i].dynamic.state.setText("")
                end
            end
            if data.wirelessMode then
                hudObjects[i].dynamic.filltime.setText("")
            else
                hudObjects[i].dynamic.filltime.setText(fillTimeString)
            end


			-- 左对齐模式下的移动函数
			local function moveForwardLeftAligned(quad, x, y, hDivisor, hProgress, energyBarLength, percentage)
                if energyData.energyPerTick > 0 then
                    local remaining = math.min((x+w-hIO-6) - (x+3+energyBarLength*percentage), ((x+w-hIO-6 - x+3) / 8))
                    quad.setColor(screen.toRGB(colors.golden))
                    if energyData.offset < 102 then
                        local xOffset = remaining * (energyData.offset/100)
                        quad.setAlpha(0.9 - (energyData.offset/100.0))
                        quad.setVertex(1, x+energyBarLength*percentage + xOffset, y+hDivisor)
                        quad.setVertex(2, x+hProgress+energyBarLength*percentage + xOffset, y+hDivisor+hProgress)
                        quad.setVertex(3, x+hProgress+energyBarLength*percentage+3 + xOffset, y+hDivisor+hProgress)
                        quad.setVertex(4, x+energyBarLength*percentage+3 + xOffset, y+hDivisor)
                    end
                else
                    local remaining = math.min((x+3+energyBarLength*percentage), energyBarLength/8)
                    quad.setColor(screen.toRGB(colors.maroon))
                    if energyData.offset < 102 then
                        local xOffset = -remaining * (energyData.offset/100)
                        quad.setAlpha(0.9 - (energyData.offset/100.0))
                        quad.setVertex(1, x+energyBarLength*percentage + xOffset, y+hDivisor)
                        quad.setVertex(2, x+hProgress+energyBarLength*percentage + xOffset, y+hDivisor+hProgress)
                        quad.setVertex(3, x+hProgress+energyBarLength*percentage+3 + xOffset, y+hDivisor+hProgress)
                        quad.setVertex(4, x+energyBarLength*percentage+3 + xOffset, y+hDivisor)
                    end
                end
                if energyData.offset > 120 then
                    energyData.offset = 0
                end
			end

			-- 右对齐模式下的移动函数
			local function moveForwardRightAligned(quad, x, y, w, hDivisor, hProgress, RightenergyBarLength, percentage)
				if energyData.energyPerTick > 0 then
					local remaining = math.min(RightenergyBarLength * (1 - percentage), RightenergyBarLength / 8)
					quad.setColor(screen.toRGB(colors.golden))
					if energyData.offset < 102 then
						local shift = remaining * (energyData.offset/100)
						local currentLeft = x + w + 5 - RightenergyBarLength * percentage
						quad.setAlpha(0.9 - (energyData.offset/100.0))
						quad.setVertex(1, currentLeft + hProgress - shift, y+hDivisor)
						quad.setVertex(2, currentLeft - shift, y+hDivisor+hProgress)
						quad.setVertex(3, currentLeft + 3 - shift, y+hDivisor+hProgress)
						quad.setVertex(4, currentLeft + hProgress + 3 - shift, y+hDivisor)
					end
				else
					local remaining = math.min(RightenergyBarLength * percentage, RightenergyBarLength / 8)
					quad.setColor(screen.toRGB(colors.maroon))
					if energyData.offset < 102 then
						local shift = remaining * (energyData.offset/100)
						local currentLeft = x + w + 5 - RightenergyBarLength * percentage
						quad.setAlpha(0.9 - (energyData.offset/100.0))
						quad.setVertex(1, currentLeft + hProgress + shift, y+hDivisor)
						quad.setVertex(2, currentLeft + shift, y+hDivisor+hProgress)
						quad.setVertex(3, currentLeft + 3 + shift, y+hDivisor+hProgress)
						quad.setVertex(4, currentLeft + hProgress + 3 + shift, y+hDivisor)
					end
				end
				if energyData.offset > 120 then
					energyData.offset = 0
				end
			end
			if hudObjects[i].rightAlign then
				moveForwardRightAligned(
					hudObjects[i].dynamic.fillIndicator,
					x, y, w,
					hDivisor, hProgress,
					RightenergyBarLength,
					percentage
				)
			else
				moveForwardLeftAligned(
					hudObjects[i].dynamic.fillIndicator,
					x, y,
					hDivisor, hProgress,
					energyBarLength,
					percentage
				)
			end
		end
	end
end
end

function powerDisplay.remove(glassAddress)
    for i = 1, #hudObjects do
        local hudObject = hudObjects[i]
        if hudObject then
            local glasses = hudObject.glasses
            if glasses ~= nil then
                if glasses.address == glassAddress then
                    for j = 1, #hudObjects[i].static do
                        hudObjects[i].glasses.removeObject(hudObjects[i].static[j].getID())
                    end
                    hudObjects[i].static = {}
                    for name, value in pairs(hudObjects[i].dynamic) do
                        hudObjects[i].glasses.removeObject(hudObjects[i].dynamic[name].getID())
                    end
                    hudObjects[i].dynamic = {}
                    hudObjects[i] = nil
                end
            end
        end
    end
end
end
return powerDisplay